prepare("SELECT * FROM exam_sessions WHERE student_id = ? AND exam_id = ? AND selected_subjects = ? AND status = 'in_progress'"); $stmt->execute([$_SESSION['student_id'], $exam_id, $selected_subjects_json]); $session = $stmt->fetch(PDO::FETCH_ASSOC); if (!$session) { // Create new session with selected subjects and generate random question order $start_time = date('Y-m-d H:i:s'); $end_time = date('Y-m-d H:i:s', strtotime("+{$exam['duration']} minutes")); $time_remaining = $exam['duration'] * 60; // Get questions only for selected subjects $placeholders = str_repeat('?,', count($selected_subjects) - 1) . '?'; $stmt = $pdo->prepare("SELECT id FROM questions WHERE exam_id = ? AND subject_id IN ($placeholders)"); $stmt->execute(array_merge([$exam_id], $selected_subjects)); $question_ids = $stmt->fetchAll(PDO::FETCH_COLUMN); // Shuffle questions for random order shuffle($question_ids); $question_order = json_encode($question_ids); $stmt = $pdo->prepare("INSERT INTO exam_sessions (student_id, exam_id, selected_subjects, start_time, end_time, time_remaining, question_order) VALUES (?, ?, ?, ?, ?, ?, ?)"); $stmt->execute([$_SESSION['student_id'], $exam_id, $selected_subjects_json, $start_time, $end_time, $time_remaining, $question_order]); $session_id = $pdo->lastInsertId(); $session = [ 'id' => $session_id, 'time_remaining' => $time_remaining, 'question_order' => $question_order ]; } else { $session_id = $session['id']; $time_remaining = $session['time_remaining']; $question_order = $session['question_order'] ?? ''; } // Handle case where question_order might be empty or invalid if (empty($question_order)) { // Regenerate question order if missing $placeholders = str_repeat('?,', count($selected_subjects) - 1) . '?'; $stmt = $pdo->prepare("SELECT id FROM questions WHERE exam_id = ? AND subject_id IN ($placeholders)"); $stmt->execute(array_merge([$exam_id], $selected_subjects)); $question_ids = $stmt->fetchAll(PDO::FETCH_COLUMN); shuffle($question_ids); $question_order = json_encode($question_ids); // Update the session with the new question order $stmt = $pdo->prepare("UPDATE exam_sessions SET question_order = ? WHERE id = ?"); $stmt->execute([$question_order, $session_id]); } // Decode question order safely $question_ids = json_decode($question_order, true) ?? []; $total_questions = count($question_ids); if ($total_questions === 0) { // Get subject names for better error message $placeholders = str_repeat('?,', count($selected_subjects) - 1) . '?'; $stmt = $pdo->prepare("SELECT name FROM subjects WHERE id IN ($placeholders)"); $stmt->execute($selected_subjects); $subject_names = $stmt->fetchAll(PDO::FETCH_COLUMN); die("No questions found for the selected subjects: " . implode(', ', $subject_names) . ". Please contact your administrator."); } // Get selected subject names for display $placeholders = str_repeat('?,', count($selected_subjects) - 1) . '?'; $stmt = $pdo->prepare("SELECT name FROM subjects WHERE id IN ($placeholders)"); $stmt->execute($selected_subjects); $selected_subject_names = $stmt->fetchAll(PDO::FETCH_COLUMN); // Handle question navigation - 5 questions per page $current_page = $_GET['page'] ?? 1; $questions_per_page = 5; $total_pages = ceil($total_questions / $questions_per_page); // Validate current page if ($current_page < 1) $current_page = 1; if ($current_page > $total_pages) $current_page = $total_pages; // Get questions for current page $start_index = ($current_page - 1) * $questions_per_page; $end_index = min($start_index + $questions_per_page, $total_questions); $current_page_question_ids = array_slice($question_ids, $start_index, $questions_per_page); // Get current page questions details $placeholders = str_repeat('?,', count($current_page_question_ids) - 1) . '?'; $stmt = $pdo->prepare("SELECT q.*, s.name as subject_name FROM questions q LEFT JOIN subjects s ON q.subject_id = s.id WHERE q.id IN ($placeholders)"); $stmt->execute($current_page_question_ids); $current_questions = $stmt->fetchAll(PDO::FETCH_ASSOC); // Reindex by question ID for easy access $current_questions_by_id = []; foreach ($current_questions as $question) { $current_questions_by_id[$question['id']] = $question; } // Get saved answers for this session to pre-fill form $stmt = $pdo->prepare("SELECT question_id, selected_answer FROM student_answers WHERE session_id = ?"); $stmt->execute([$session_id]); $saved_answers = $stmt->fetchAll(PDO::FETCH_KEY_PAIR); // Handle answer saving (save without submitting) if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (isset($_POST['save_answer']) || isset($_POST['next']) || isset($_POST['previous']) || isset($_POST['save_all'])) { // Handle multiple questions submission if (isset($_POST['selected_answers']) && is_array($_POST['selected_answers'])) { foreach ($_POST['selected_answers'] as $question_id => $selected_answer) { if (!empty($selected_answer)) { // Check if answer already exists $stmt = $pdo->prepare("SELECT id FROM student_answers WHERE session_id = ? AND question_id = ?"); $stmt->execute([$session_id, $question_id]); if ($stmt->rowCount() > 0) { // Update existing answer $stmt = $pdo->prepare("UPDATE student_answers SET selected_answer = ? WHERE session_id = ? AND question_id = ?"); $stmt->execute([$selected_answer, $session_id, $question_id]); } else { // Insert new answer $stmt = $pdo->prepare("INSERT INTO student_answers (session_id, question_id, selected_answer) VALUES (?, ?, ?)"); $stmt->execute([$session_id, $question_id, $selected_answer]); } // Update saved answers array $saved_answers[$question_id] = $selected_answer; } } } // Update time remaining $time_remaining = $_POST['time_remaining'] ?? $time_remaining; $stmt = $pdo->prepare("UPDATE exam_sessions SET time_remaining = ? WHERE id = ?"); $stmt->execute([$time_remaining, $session_id]); // Redirect based on action if (isset($_POST['next'])) { $next_page = min($current_page + 1, $total_pages); redirect("exam.php?exam_id=$exam_id&page=$next_page"); } elseif (isset($_POST['previous'])) { $prev_page = max($current_page - 1, 1); redirect("exam.php?exam_id=$exam_id&page=$prev_page"); } elseif (isset($_POST['save_all'])) { // Show success message and stay on current page $_SESSION['save_message'] = "All answers saved successfully!"; redirect("exam.php?exam_id=$exam_id&page=$current_page"); } else { // Stay on current page if just saving redirect("exam.php?exam_id=$exam_id&page=$current_page"); } } } // Handle final submission if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['submit_exam'])) { // Update time remaining first $time_remaining = $_POST['time_remaining'] ?? $time_remaining; $stmt = $pdo->prepare("UPDATE exam_sessions SET time_remaining = ? WHERE id = ?"); $stmt->execute([$time_remaining, $session_id]); // Update all answers with correctness and submit exam $stmt = $pdo->prepare(" UPDATE student_answers sa JOIN questions q ON sa.question_id = q.id SET sa.is_correct = (q.correct_answer = sa.selected_answer) WHERE sa.session_id = ? "); $stmt->execute([$session_id]); // Submit exam $stmt = $pdo->prepare("UPDATE exam_sessions SET status = 'completed', time_remaining = 0 WHERE id = ?"); $stmt->execute([$session_id]); // Calculate and save result $correct_answers = calculate_score($session_id, $pdo); $questions_attempted = count($saved_answers); $percentage = ($correct_answers / $total_questions) * 100; $stmt = $pdo->prepare("INSERT INTO results (session_id, total_questions, questions_attempted, correct_answers, score, percentage) VALUES (?, ?, ?, ?, ?, ?)"); $stmt->execute([$session_id, $total_questions, $questions_attempted, $correct_answers, $correct_answers, $percentage]); // Clear selected subjects from session after exam completion unset($_SESSION['selected_subjects']); unset($_SESSION['current_exam_id']); redirect("result.php?session_id=$session_id"); } ?> Exam - <?php echo $exam['name']; ?>

()

Selected Subjects:

Total Questions: | Page: of

Time:
Showing questions - of | Answered: /
$question_id): $question = $current_questions_by_id[$question_id] ?? null; if (!$question) continue; $question_number = $start_index + $index + 1; $current_answer = $saved_answers[$question_id] ?? null; ?>

Question

( mark 1 ? 's' : ''; ?>)

$question['option_a'], 'B' => $question['option_b'], 'C' => $question['option_c'], 'D' => $question['option_d'] ]; foreach ($options as $letter => $option_text): $is_checked = $current_answer === $letter; ?>
Answers saved successfully!